//
//  UserNotificationManager.m
//  AgendaManager
//
//  Created by 黄世淞 on 2018/5/28.
//  Copyright © 2018年 黄世淞. All rights reserved.
//

#import "UserNotificationManager.h"

@implementation UserNotificationManager
/**
 注册本地通知
 */
+ (void)registerLocalNotification{
    UNUserNotificationCenter * center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (!error) {
            NSLog(@"request successed!");
        }
    }];
    [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
        NSLog(@"%@",settings);
    }];
    UNNotificationAction * action1 = [UNNotificationAction actionWithIdentifier:ActionFiveMin title:@"5分钟后" options:UNNotificationActionOptionNone];
    UNNotificationAction * action2 = [UNNotificationAction actionWithIdentifier:ActionHalfAnHour title:@"30分钟后" options:UNNotificationActionOptionNone];
    UNNotificationAction * action3 = [UNNotificationAction actionWithIdentifier:ActionOneHour title:@"1小时后" options:UNNotificationActionOptionNone];
    UNNotificationAction * action4 = [UNNotificationAction actionWithIdentifier:ActionStop title:@"停止" options:UNNotificationActionOptionNone];
    UNNotificationCategory * laterCategory = [UNNotificationCategory categoryWithIdentifier:CategryLaterIdf actions:@[action1,action2,action3,action4] intentIdentifiers:@[] options:UNNotificationCategoryOptionNone];
    UNNotificationCategory * stopCategory = [UNNotificationCategory categoryWithIdentifier:CategryStopIdf actions:@[action4] intentIdentifiers:@[] options:UNNotificationCategoryOptionNone];
    [center setNotificationCategories:[NSSet setWithArray:@[laterCategory,stopCategory]]];
}
#pragma mark --- addNotification

/**
 添加通知
 
 @param request 通知请求
 */
+ (void)addNotificationWithRequest:(UNNotificationRequest *)request
                 completionHandler:(void(^)(NSError * error))handler{
    [[self center] addNotificationRequest:request withCompletionHandler:handler];
}


/**
 添加通知
 
 @param content 通知内容
 @param identifer 通知标识符
 @param trigger 通知触发器
 */
+ (void)addNotificationWithContent:(UNNotificationContent *)content
                         identifer:(NSString *)identifer
                           trigger:(UNNotificationTrigger *)trigger
                 completionHandler:(void (^)(NSError * error))handler{
    UNMutableNotificationContent * aContent = [content mutableCopy];
    if ([identifer hasPrefix:isLater]) {
        aContent.categoryIdentifier = CategryLaterIdf;
    }else{
        aContent.categoryIdentifier = CategryStopIdf;
    }
    UNNotificationRequest * request = [UNNotificationRequest requestWithIdentifier:identifer content:aContent trigger:trigger];
    [self addNotificationWithRequest:request completionHandler:handler];
}

/**
 添加通知
 
 @param content 通知内容
 @param interval 通知间隔
 @param identifer 通知标识符
 @param isRepeat 是否重复
 */
+ (void)addNotificationWithContent:(UNNotificationContent *)content
                          interval:(NSTimeInterval)interval
                         identifer:(NSString *)identifer
                          isRepeat:(BOOL)isRepeat
                 completionHandler:(void (^)(NSError * error))handler{
    [self addNotificationWithContent:content identifer:identifer trigger:[self triggerWithTimeInterval:interval repeats:isRepeat] completionHandler:handler];
}

/**
 添加通知
 
 @param content 通知内容
 @param identifer 通知标识符
 @param isRepeat 是否重复
 @param dateComponents 日期组件
 */
+ (void)addNotificationWithContent:(UNNotificationContent *)content
                         identifer:(NSString *)identifer
                          isRepeat:(BOOL)isRepeat
                    dateComponents:(NSDateComponents *)dateComponents
                 completionHandler:(void (^)(NSError * error))handler{
    [self addNotificationWithContent:content identifer:identifer trigger:[self triggerWithDateComponents:dateComponents repeats:isRepeat] completionHandler:handler];
}

/**
 添加通知
 
 @param content 通知内容
 @param identifer 通知标识符
 @param isRepeat 是否重复
 @param date 日期
 @param weekDay 星期几
 */
+ (void)addNotificationWithContent:(UNNotificationContent *)content
                         identifer:(NSString *)identifer
                          isRepeat:(BOOL)isRepeat
                              date:(NSDate *)date
                           weekDay:(NSInteger)weekDay
                 completionHandler:(void (^)(NSError * error))handler{
    [self addNotificationWithContent:content identifer:identifer isRepeat:isRepeat dateComponents:[self componentsWithDate:date weekday:weekDay] completionHandler:handler];
}

/**
 添加通知
 
 @param body 通知主体
 @param title 通知标题
 @param subTitle 通知子标题
 @param weekDay 星期几
 @param date 日期
 @param music 音乐
 @param identifer 标识符
 @param isRepeat 是否重复
 */
+ (void)addNotificationWithBody:(NSString *)body
                          title:(NSString *)title
                       subTitle:(NSString *)subTitle
                        weekDay:(NSInteger)weekDay
                           date:(NSDate *)date
                          music:(NSString *)music
                      identifer:(NSString *)identifer
                       isRepeat:(BOOL)isRepeat
              completionHandler:(void (^)(NSError * error))handler{
    UNNotificationContent * content = [self contentWithTitle:title subTitle:subTitle body:body sound:[UNNotificationSound soundNamed:music]];
    [self addNotificationWithContent:content identifer:identifer isRepeat:isRepeat date:date weekDay:weekDay completionHandler:handler];
}

#pragma mark --- NotificationManage

/**
 移除一个指定的通知
 
 @param identifer 标识符
 */
+ (void)removeNotificationWithIdentifer:(NSString *)identifer{
    //移除已展示过的
    [[self center] removeDeliveredNotificationsWithIdentifiers:@[identifer]];
    //移除未展示过的
    [[self center] removePendingNotificationRequestsWithIdentifiers:@[identifer]];
}
/**
 移除所有通知
 */
+ (void)removeAllNotification{
    [self getAllNotificationIdentiferBlock:^(NSArray<NSString *> *identifers) {
        [self removeNotificationWithIdentifers:identifers];
    }];
}

/**
 移除多个通知
 
 @param identifers 多个标识符数组
 */
+ (void)removeNotificationWithIdentifers:(NSArray <NSString *>*)identifers{
    //移除已展示过的
    [[self center] removeDeliveredNotificationsWithIdentifiers:identifers];
    //移除未展示过的
    [[self center] removePendingNotificationRequestsWithIdentifiers:identifers];
}

/**
 判断某个通知是否存在
 
 @param identifer 标识符
 @param completion 判断结果
 */
+ (void)notificationIsExitWithIdentifer:(NSString *)identifer completion:(void (^)(BOOL isExit))completion{
    [self getAllNotificationIdentiferBlock:^(NSArray<NSString *> *identifers) {
        [identifers enumerateObjectsUsingBlock:^(NSString * obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([obj isEqualToString:identifer]) {
                completion(YES);
                *stop = YES;
            }
        }];
        completion(NO);
    }];
}

/**
 获取所有通知的标识符
 */
+ (void)getAllNotificationIdentiferBlock:(void(^)(NSArray <NSString *> * identifers))idBlock{
    [[self center] getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
        NSMutableArray * array = [NSMutableArray array];
        [notifications enumerateObjectsUsingBlock:^(UNNotification * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [array addObject:obj.request.identifier];
        }];
        [[self center] getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> * _Nonnull requests) {
            [requests enumerateObjectsUsingBlock:^(UNNotificationRequest * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                [array addObject:obj.identifier];
            }];
            if (idBlock) {
                idBlock([array copy]);
            }
        }];
    }];
}

/**
 获取已交付的标识符
 */
+ (void)getDeliveredNotificationIdentiferBlock:(void(^)(NSArray <NSString *> * identifers))idBlock{
    [[self center] getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
        NSMutableArray * array = [NSMutableArray array];
        [notifications enumerateObjectsUsingBlock:^(UNNotification * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [array addObject:obj.request.identifier];
        }];
        if (idBlock) {
            idBlock([array copy]);
        }
    }];
}

/**
 获取的标识符
 */
+ (void)getPendingNotificationIdentiferBlock:(void(^)(NSArray <NSString *> * identifers))idBlock{
    [[self center] getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> * _Nonnull requests) {
        NSMutableArray * array = [NSMutableArray array];
        [requests enumerateObjectsUsingBlock:^(UNNotificationRequest * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [array addObject:obj.identifier];
        }];
        if (idBlock) {
            idBlock([array copy]);
        }
    }];
}


















#pragma mark --- UNNotificationContent

/**
 通知内容
 
 @param title 标题
 @param subTitle 子标题
 @param body 主体
 */
+ (UNMutableNotificationContent *)contentWithTitle:(NSString *)title
                                          subTitle:(NSString *)subTitle
                                              body:(NSString *)body{
    NSString * titleStr = title.length > 0 ? title : @"提醒";
    NSString * bodyStr = body.length > 0 ? body : @"提醒";
    UNMutableNotificationContent * content = [[UNMutableNotificationContent alloc]init];
    content.title = titleStr;
    content.subtitle = subTitle;
    content.body = bodyStr;
    content.sound = [UNNotificationSound defaultSound];
    return content;
}

/**
 @param badge 标记
 */
+ (UNMutableNotificationContent *)contentWithTitle:(NSString *)title
                                          subTitle:(NSString *)subTitle
                                              body:(NSString *)body
                                             badge:(NSInteger)badge{
    UNMutableNotificationContent * content = [self contentWithTitle:title subTitle:subTitle body:body];
    content.badge = @(badge);
    return content;
}
/**
 @param sound 声音
 */
+ (UNMutableNotificationContent *)contentWithTitle:(NSString *)title
                                          subTitle:(NSString *)subTitle
                                              body:(NSString *)body
                                             sound:(UNNotificationSound *)sound{
    UNMutableNotificationContent * content = [self contentWithTitle:title subTitle:subTitle body:body];
    content.sound = sound;
    return content;
}
+ (UNMutableNotificationContent *)contentWithTitle:(NSString *)title
                                          subTitle:(NSString *)subTitle
                                              body:(NSString *)body
                                             badge:(NSInteger)badge
                                             sound:(UNNotificationSound *)sound{
    UNMutableNotificationContent * content = [self contentWithTitle:title subTitle:subTitle body:body badge:badge];
    content.sound = sound;
    return content;
}
/**
 @param attachment 附件
 */
+ (UNMutableNotificationContent *)contentWithTitle:(NSString *)title
                                          subTitle:(NSString *)subTitle
                                              body:(NSString *)body
                                             badge:(NSInteger)badge
                                             sound:(UNNotificationSound *)sound
                                        attachment:(UNNotificationAttachment *)attachment{
    UNMutableNotificationContent * content = [self contentWithTitle:title subTitle:subTitle body:body badge:badge sound:sound];
    content.attachments = @[attachment];
    return content;
}
/**
 @param attachment 多个附件
 */
+ (UNMutableNotificationContent *)contentWithTitle:(NSString *)title
                                          subTitle:(NSString *)subTitle
                                              body:(NSString *)body
                                             badge:(NSInteger)badge
                                             sound:(UNNotificationSound *)sound
                                       attachments:(NSArray<UNNotificationAttachment *> *)attachments{
    UNMutableNotificationContent * content = [self contentWithTitle:title subTitle:subTitle body:body badge:badge sound:sound];
    content.attachments = attachments;
    return content;
}


#pragma mark --- NSDateComponents

/**
 日期组件
 
 @param date 日期
 @return 返回一个带有年月日时分秒的日期组件 不会重复
 */
+ (NSDateComponents *)componentsWithDate:(NSDate *)date{
    NSInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth |NSCalendarUnitDay |NSCalendarUnitHour | NSCalendarUnitMinute;
    NSDateComponents * components = [[NSCalendar currentCalendar] components:unitFlags fromDate:date];
    return components;
}

/**
 日期组件
 
 @param date 日期
 @param weekday 指定星期几  1-7对应星期日-星期六
 @return 周时分秒  每周重复
 */
+ (NSDateComponents *)componentsWithDate:(NSDate *)date weekday:(NSInteger)weekday{
    NSInteger unitFlags =NSCalendarUnitHour | NSCalendarUnitMinute;
    NSDateComponents * components = [[NSCalendar currentCalendar] components:unitFlags fromDate:date];
    components.weekday = weekday;
    return components;
}

/**
 日期组件
 
 @param date 日期
 @return 时分秒 每日重复
 */
+ (NSDateComponents *)componentsWithEveryDayWithDate:(NSDate *)date{
    NSInteger unitFlags =NSCalendarUnitHour | NSCalendarUnitMinute;
    NSDateComponents * components = [[NSCalendar currentCalendar] components:unitFlags fromDate:date];
    return components;
}
/**
 日期组件
 
 @param date 日期
 @return 时分秒 每周重复
 */
+ (NSDateComponents *)componentsWithEveryWeekWithDate:(NSDate *)date{
    NSInteger unitFlags =NSCalendarUnitHour | NSCalendarUnitMinute|NSCalendarUnitWeekday;
    NSDateComponents * components = [[NSCalendar currentCalendar] components:unitFlags fromDate:date];
    return components;
}
/**
 日期组件
 
 @param date 日期
 @return 时分秒 每月重复
 */
+ (NSDateComponents *)componentsWithEveryMonthWithDate:(NSDate *)date{
    NSInteger unitFlags =NSCalendarUnitHour | NSCalendarUnitMinute|NSCalendarUnitDay;
    NSDateComponents * components = [[NSCalendar currentCalendar] components:unitFlags fromDate:date];
    return components;
}
/**
 日期组件
 
 @param date 日期
 @return 时分秒 每年重复
 */
+ (NSDateComponents *)componentsWithEveryYearWithDate:(NSDate *)date{
    NSInteger unitFlags =NSCalendarUnitHour | NSCalendarUnitMinute|NSCalendarUnitDay|NSCalendarUnitMonth;
    NSDateComponents * components = [[NSCalendar currentCalendar] components:unitFlags fromDate:date];
    return components;
}



#pragma mark -- UNNotificationTrigger

/**
 通知触发器
 
 @param components 日期组件
 @param repeats 是否重复
 */
+ (UNNotificationTrigger *)triggerWithDateComponents:(NSDateComponents *)components
                                             repeats:(BOOL)repeats{
    return [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:repeats];
}

/**
 通知触发器
 
 @param interval 通知间隔
 @param repeats 是否重复
 */
+ (UNNotificationTrigger *)triggerWithTimeInterval:(NSTimeInterval)interval
                                           repeats:(BOOL)repeats{
    return [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:interval repeats:repeats];
}

/**
 通知触发器
 
 @param region 地理信息
 @param repeats 是否重复
 */
+ (UNNotificationTrigger *)triggerWithRegion:(CLRegion *)region
                                     repeats:(BOOL)repeats{
    return [UNLocationNotificationTrigger triggerWithRegion:region repeats:repeats];
}












#pragma mark --- paivate
+ (UNUserNotificationCenter *)center{
    return [UNUserNotificationCenter currentNotificationCenter];
}





@end
